package drds.server.route.parser.core;

import java.sql.SQLNonTransientException;

import drds.server.cache.LayeredCache;
import drds.server.config.model.Schema;
import drds.server.route.Route;
import drds.server.sqlparser.sqlobject.statement.Statement;

/**
 * <pre>
 * DRDS不支持子查询和跨库的join查询。
 * </pre>
 * 
 * 对SQLStatement解析 主要通过visitor解析和statement解析：有些类型的SQLStatement通过visitor解析足够了，
 * 有些只能通过statement解析才能得到所有信息 有些需要通过两种方式解析才能得到完整信息
 */
public interface SqlParser {
	/**
	 * 得到tables、tableAliasMap、conditions等
	 */
	public void parseSql(//
			Route route,//
			String sql,//
			Schema schema,//
			Statement statement, //
			ShardInfoVisitor visitor,//
			LayeredCache cache) throws SQLNonTransientException;//

	/**
	 * statement方式解析 子类可覆盖（如果visitorParse解析得不到表名、字段等信息的，就通过覆盖该方法来解析）
	 * 子类覆盖该方法一般是将SQLStatement转型后再解析（如转型为MySqlInsertStatement）
	 */
	public void statementParse(//
			Route route, //
			Schema schema,//
			Statement statement) throws SQLNonTransientException;//

	/**
	 * 子类可覆盖（如果该方法解析得不到表名、字段等信息的，就覆盖该方法，覆盖成空方法，然后通过statementPparse去解析）
	 * 通过visitor解析：有些类型的Statement通过visitor解析得不到表名、
	 */
	public void visitorParse(Route route, Statement statement, ShardInfoVisitor visitor) throws SQLNonTransientException;

	/**
	 * 改写sql：加limit，加group by、加order by如有些没有加limit的可以通过该方法增加
	 */
	public void changeSql(Schema schema, Route route, Statement statement, LayeredCache cache) throws SQLNonTransientException;

	/**
	 * 获取解析到的信息
	 */
	public ParserResult getParserResult();

}
